<template>
    <div>
      <el-upload
      class="upload-demo"
      ref="uploadApk"
      action="http://xf-api.muranzhidian.cn/api/file/files/qiniu/upload"
      :on-success="handleSuccess"
      :auto-upload="autoUpload"
      :data="postData"
      :on-change="fileChange"
      :before-upload="beforeUpload"
      :file-list="apkFile" style="width: 200px;">
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">只能上传apk文件，且不超过100MB</div>
      </el-upload>
    </div>
</template>
<script>
import { mapGetters } from "vuex";
import VueCropper from "vue-cropperjs";
import ImageCover from "@/components/image-cover";
import CloseBtn from "@/components/close-btn";
import FileAPI from "fileapi/dist/FileAPI.html5";
import md5 from "js-md5";
import axios from "axios";
import Api from "api/api";

const axiosInstance = axios.create({});

export default {
  props: {
    value: String,
    maxSize: {
      type: Number,
      default: 512
    },
    accept: String,
    title: {
      type: String,
      default: "上传文件"
    },
    width: Number,
    height: Number,
    multi: {
      type: Number,
      default: 1
    }
  },
  created() {
    this.uuid = Math.random()
      .toString(36)
      .substring(3, 8);
  },
  mounted() {
    if (this.value && this.value.length) {
      this.result = this.value.split(",");
    } else {
      this.result = [];
    }

    this.$watch("value", val => {
      if (val && val.length) {
        this.result = val.split(",");
      } else {
        this.result = [];
      }
    });

    this.$watch(
      "result",
      val => {
        console.log("watch", val);
        if (val.length) {
          this.$emit("input", val.join(","));
        } else {
          this.$emit("input", "");
        }
      },
      { deep: true }
    );
  },
  data() {
    return {
      key: "",
      token: "",
      url: "//upload.qiniu.com/",
      currentFile: {},
      result: [],
      imageSrc: "",
      cropImg: "",
      theFile: {},
      showCropper: false,
      uploadStatus: 0, // 0 未开始 1 上传中 2 已上传
      uploadPercent: 0,
      uploading: false,
      localUpload: false
    };
  },
  computed: {
    imageThumbStyle() {
      return { width: `${this.width / 2}px`, height: `${this.height / 2}px` };
    }
  },
  methods: {
    selectFile: async function(e) {
      const file = e.target.files[0];
      this.currentFile = file;

      if (this.result.length >= this.multi) {
        this.$refs.userfile.value = null;
        this.$emit("on-error", { message: `最多上传${this.multi}个文件` });
        console.log(`最多上传${this.multi}个文件`);
        return false;
      }

      const isAcceptType = new RegExp("image/*", "i").test(file.type);

      if (!isAcceptType) {
        this.$refs.userfile.value = null;
        this.$emit("on-error", { message: `请选择apk类型文件` });
        console.log(`请选择apk类型文件`);
        return false;
      }

      if (file.size > this.maxSize * 1000) {
        this.$refs.userfile.value = null;
        this.$emit("on-error", {
          message: `请上传小于${this.maxSize}KB的文件`
        });
        console.log(`请上传小于${this.maxSize}KB的文件`);
        return false;
      }

      let tmp = `${file.lastModified + file.size + Date.now()}`;
      let nameArr = file.name.split(".");
      let extName = nameArr[nameArr.length - 1];
      this.key = md5(tmp).substr(0, 10) + "_" + "." + extName;
      if (this.localUpload) {
        this.token = window.sessionStorage.getItem("token");
      } else {
        this.token = await this.getToken(this.key);
      }

      if (this.token) {
        this.uploading = true;
        let url = await this.uploadQN(file, this.token, this.key);
        this.uploading = false;
      } else {
        this.$refs.userfile.value = null;
      }
    },
    previewFile(file) {
      FileAPI.Image(file)
        .resize(800, 800, "max")
        .get((err, img) => {
          if (!err) {
            this.imageSrc = img.toDataURL();
            this.$refs.cropper.replace(this.imageSrc);
          }
        });
    },
    cropImage() {
      this.cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL();
    },
    getToken(key) {
      return Api.getUploadFileToken({ fileName: key }).then(ret => {
        return ret.data.data.token;
      });
    },
    clean() {
      this.$refs.userfile.value = null;
      this.result = [];
      this.$emit("on-clean");
    },
    cancelCrop() {
      this.showCropper = false;
      this.clean();
    },
    confirmCrop: async function() {
      this.uploading = true;
      const file = this.canvasToFile(
        this.$refs.cropper.getCroppedCanvas(),
        this.currentFile.name
      );
      let imgUrl = await this.uploadQN(file, this.token, this.key);
      this.uploading = false;
      this.showCropper = false;
    },
    canvasToFile(canvas, filename) {
      const dataUrl = canvas.toDataURL();
      const blob = this._dataURLtoBlob(dataUrl);
      return new File([blob], filename);
    },
    _dataURLtoBlob(dataurl) {
      var arr = dataurl.split(",");
      var mime = arr[0].match(/:(.*?);/)[1];
      var bstr = atob(arr[1]);
      var n = bstr.length;
      var u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
    uploadQN(file, token, key) {
      var fd = new FormData();
      fd.append("token", token);
      fd.append("key", key);
      fd.append("file", file);

      return axiosInstance({
        method: "POST",
        url: this.$appConf.domain.uploadUrl,
        data: fd,
        onUploadProgress: function(progressEvent) {
          var percentCompleted = Math.round(
            (progressEvent.loaded * 100) / progressEvent.total
          );
          console.log(percentCompleted);
        }
      })
        .then(res => {
          this.uploadStatus = 2;
          if (this.localUpload) {
            this.result.push(res.data.data.fileName);
            this.$refs.userfile.value = null;
            return res.data.data.fileUrl;
          } else {
            this.result.push(res.data.data.fileName);
            this.$refs.userfile.value = null;
            return `${window.api.imageDomain}${res.data.key}`;
          }
        })
        .catch(err => {
          console.log("err", err);
          this.clean();
        });
    },
    deleteImage(index) {
      this.result.splice(index, 1);
    }
  },
  components: {
    VueCropper,
    ImageCover,
    CloseBtn
  }
};
</script>
<style>
.upload-button > * {
  pointer-events: none;
}
.upload-button {
  display: block;
  width: 300px;
  min-height: 150px;
  margin: 10px auto auto auto;
  padding: 10px auto;
  border-radius: 10px;
  border: 2px dashed #ddd;
  overflow: hidden;
  cursor: pointer;
}
.upload-button span {
  display: block;
  width: 50px;
  height: 50px;
  border-radius: 100%;
  border: 3px solid #0983c7;
  margin: 30px auto 15px;
  position: relative;
}
.upload-button em {
  font-style: normal;
  text-align: center;
  display: block;
}
.upload-button span:before,
.upload-button span:after {
  display: block;
  content: "";
  background-color: #0983c7;
  position: absolute;
}
.upload-button span:before {
  width: 3px;
  height: 30px;
  top: 10px;
  left: 24px;
}
.upload-button span:after {
  width: 30px;
  height: 3px;
  top: 24px;
  left: 10px;
}

.audio-preview {
  width: 100%;
  position: relative;
}
.video-preview {
  width: 100%;
  position: relative;
}

.image-cropper {
  position: relative;
}
.cropper-buttons {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(255, 255, 255, 0.6);
}
.btn {
  padding: 10px;
}
.btn-primary {
  background-color: rgba(235, 97, 0, 0.8);
  color: #fff;
}

/* 多图上传相关 */
.image-preview {
  position: relative;
}
.image-list {
  list-style: none;
  display: inline-block;
  margin: 0;
  padding: 0;
}
.image-list li {
  float: left;
  border: 1px solid #e8f5ff;
  position: relative;
}
.upload-image-button {
  width: 100px;
  height: 100px;
  position: relative;
  border: 2px dashed #ddd !important;
  box-sizing: border-box;
}
.plus {
  font-size: 70px;
  color: #0983c7;
  line-height: 70px;
  margin-bottom: 15px;
  font-weight: 200;
  cursor: pointer;
}
.delete-btn {
  top: -8px;
  right: -5px;
  position: absolute !important;
  cursor: pointer;
}
</style>
